iT邦幫忙

DAY 15
2

emacs的30天學習筆記系列 第 28

懷舊C語言:1988年出版 The C Programming Language 2nd Edition

  • 分享至 

  • xImage
  •  

這本書的另一作者,Brian Kernighan,相對來說,沒有那麼出名,特別google了他。
http://en.wikipedia.org/wiki/Brian_Kernighan
http://www.cs.princeton.edu/~bwk/
現在仍在普林斯頓大學教書。
如果是一unix歷史的粉絲,對他會很有意思,畢竟他貢獻了很多基礎工具,
以AWK這個工具而言,K指的就是他老人家。雖然這工具非unix like的人幾乎沒用過。
由AWK這工具,大概可知道這位老人家生平對程式語言的興趣菲淺。

在1988年時,C語言就是系統程式的首選語言,意思是商用語言,它不太適合。
書中很多例子,都會參照pascal和fortran的語法。
表示在當時,這兩個語言普及率很高了。

C語言經歷多次的標準修訂,所以這個1988年版,就是所謂K&R 的C語言規格書。

這麼經典,頁數不到300頁。

大專院校似乎很少用這本做教科書。反而用厚到讓人望之生畏的書。

C語言,有一分GCC, 還是和linux核心,一直再發展,支援一些新的特色,並沒有停滯發展,
甚至在核心裏的一些特殊語法,導致其他C語言編譯器不能成功編譯,為此INTEL 的C, ICC就為此
做了修改,以相容GCC.


書很小本,為了確認有讀進去了,以練習習題來確認。順便也確認一下這本23年的老書(2011-1988)的code還能不能在gcc編譯成功。


相對於C++之父親手撰寫的第三版,至少一千頁起跳的大書,這本書果然袖珍多了。
第一章:入門學習。
當然又從hello world開始,只是它是史上最早這樣用,如果不是它這樣用,可能所有語言的第一個練習程式要改寫了。
題1:

Exercise 1-1. Run the ``hello, world'' program on your system. Experiment with leaving out parts of the
program, to see what error messages you get.

不太懂它的意思,
大概是把程式,隨便改改,看會得到什麼錯誤訊息?
$ gcc helloworld.c
include 拿掉,或**;拿掉,或{**去掉一個試試。

helloworld.c: In function ‘main’:
helloworld.c:6: warning: incompatible implicit declaration of built-in function ‘printf’
timloo@ubuntu:~/gccExc$ gcc helloworld.c
helloworld.c: In function ‘main’:
helloworld.c:6: error: expected declaration specifiers before ‘printf’
helloworld.c:7: error: expected declaration specifiers before ‘printf’
helloworld.c:8: error: expected declaration specifiers before ‘printf’
helloworld.c:9: error: expected declaration specifiers before ‘}’ token
helloworld.c:9: error: expected ‘{’ at end of input
timloo@ubuntu:~/gccExc$ gcc helloworld.c
helloworld.c:6:11: warning: missing terminating " character
helloworld.c: In function ‘main’:
helloworld.c:6: error: missing terminating " character
helloworld.c:7: error: expected ‘)’ before ‘;’ token
helloworld.c:9: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast
/usr/include/stdio.h:339: note: expected ‘const char * __restrict__’ but argument is of type ‘int’
helloworld.c:9: warning: format not a string literal and no format arguments
helloworld.c:9: error: expected ‘;’ before ‘}’ token
題2

Exercise 1-2. Experiment to find out what happens when prints's argument string contains \c, where c is some
character not listed above.

試一下**\c**

helloworld.c:6:11: warning: unknown escape sequence '\c'

只有**\n (new line) \t (TAB),** 沒特別想這個問題,pass過了。

題3:

Exercise 1-3. Modify the temperature conversion program to print a heading above the table.

加上表頭(heading ),
加上

printf("fahr | \t celsi \n");
   while (fahr<=upper)
     {
       celsius = 5*(fahr-32)/9;
       printf("%6d  | \t%6xd | \n  ",fahr,celsius);
       fahr=fahr+step;

     }

題4:

Exercise 1-4. Write a program to print the corresponding Celsius to Fahrenheit table.

範例是華氏轉攝氏,本題換成攝氏轉華氏。

 #include <stdio.h>
 main()
 {
   int fahr ,celsius;
   int lower,upper,step;

   lower=0;
   upper=300;
   step=20;

   celsius=lower;
   printf("   celsi    | \t fahr \n");
   while (celsius<=upper)
     {
       //       celsius = 5*(fahr-32)/9;
       fahr = 9*celsius/5+32;
       printf("%6d  | \t%6d | \n  ",celsius,fahr);
       celsius=celsius+step;
     }
 }

把轉換的公式,反轉一下。
順便練習一下編輯器的取代

題5:

Exercise 1-5. Modify the temperature conversion program to print the table in reverse order, that is, from 300
degrees to 0.

範例是0 到300的for 迴圈,改成300到0的迴圈。

#include <stdio.h>
 main()
 {
   printf("   celsi    | \t fahr \n");
   for ( int fahr = 300; fahr>=0; fahr=fahr-20)
     {

       printf("%3d  | \t%6.1f  | \n  ",fahr,(5.0/9.0)*(fahr-32)
);
     }
 }

做相對應的修改,原範例用while,用for改寫一遍,for精簡多了。

timloo@ubuntu:~/gccExc$ gcc fortempr.c
fortempr.c: In function ‘main’:
fortempr.c:8: error: ‘for’ loop initial declarations are only allowed in C99 mode
fortempr.c:8: note: use option -std=c99 or -std=gnu99 to compile your code
timloo@ubuntu:~/gccExc$ gcc -std=c99 fortempr.c
fortempr.c:5: warning: return type defaults to ‘int’

我在for 迴圈裏宣告int,gcc預設是編譯不過的,加上**-std=c99**可過。
編譯器是很敏感的,而規格定義的很細。
題六:

Exercsise 1-6. Verify that the expression getchar() != EOF is 0 or 1.

書上沒提到EOF 怎麼用鍵盤輸入,筆者用Ctrl-d來代替。有興趣的讀者可以google。比較怪的是,筆者進入gdb trace。

(gdb) p EOF
No symbol "EOF" in current context.
(gdb) p getchar() != EOF
No symbol "EOF" in current context.

gdb 不認得EOF, 編譯也沒有錯。

所以,這題可能可以反相思考,while(1)
還是while(0),程式會進while迴圈,
可以推出 while ((c = getchar())!= EOF)是0還是1,
書上有講,(c = getchar())!= EOF 等同於
c = getchar()!= EOF,把 getchar())!= EOF比較後的結果給 c。

這樣可推論。

題七:

Exercise 1-7. Write a program to print the value of EOF.

筆者用 printf("%d \n \n",EOF);,印出來的值是**-1**
可是getchar(),你輸入-1,它會想成,-1, 所以筆者輸入-1,
並不會有EOF,讓程式結束的效果,還是用Ctrl - d

題8:

Exercise 1-8. Write a program to count blanks, tabs, and newlines.

參考範例,略做修改。

#include <stdio.h>


 main()
 {

   int c,nl=0,nt=0,nb=0;

   //   nl = 0;
   while ((c = getchar())!= EOF)
     {
       if (c== '\n')
         ++nl;
       if (c== ' ')
         ++nb;
       if (c== '\t')
         ++nt;
     }
   printf("line count is %d, tab count is %d ,blank count is %d  \n\n",nl,nt,nb);

 }

算出 tab,blank,new line,這些符號出現的次數。
題9:

Exercise 1-9. Write a program to copy its input to its output, replacing each string of one or more blanks by a
single blank.

暫時還做不出來,題意好像是把一個及以上的空白,抽換成單一個空白。
覺得範例,不足以做到此事,可能要兩個陣列,才能做,或是誤解題意。

題10:

Exercise 1-10. Write a program to copy its input to its output, replacing each tab by \t, each backspace by \b,
and each backslash by \\. This makes tabs and backspaces visible in an unambiguous way.

把tab 換成\t,backspace換成 \b,backslash 換成 \\.

 #include <stdio.h>
 main()
 {
   int c,nl=0,nt=0,nb=0;
   while ((c = getchar())!= EOF)
     {
       if (c== ' ')
         printf("\\b");
       else
         {
         if (c== '\t')
         printf("\\t");
       else
       {
         if (c=='\\')
         printf("\\\\");
          else
            putchar(c);
       }
         }
     }

 }

小結:因為堂弟上大夜班,又加班2個小時,沒按時繳網路連線費用,真的斷了3天線。
果然30天持續發文充滿著變數,尤其是上班時,有時很涼,有時很操,操時,真沒心思
思考。一段時間沒用gcc,再用時又陌生了,最好還是每天都用,才把不適的感覺降低。


上一篇
emacs 做中學第二十六天:繼續gsoap client
下一篇
那些Web Service的往事
系列文
emacs的30天學習筆記38
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
neverbig
iT邦新手 4 級 ‧ 2011-11-08 19:42:51

請問timloo大大,你使用怎樣的gcc環境?
如果在windows 7下也可以如同你這樣run嗎?
因為看大大這樣玩老古董,突然有一種感動啊~

我要留言

立即登入留言